<?php
declare(strict_types=1);

namespace App\Utils;

use App\Constants\XZXResponseCode;
use Hyperf\Utils\Context;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;

// use Hyperf\HttpServer\Contract\ResponseInterface;
use Throwable;

/**
 * 自定义函数类
 * Class CustomUtils
 *
 * @package App\Utils
 */
class CustomUtils {

    public static function xeServiceReturnData (int $code, string $message = '', $data = []): array {
        $result = [
            'code'    => $code,
            'message' => $message,
            'data'    => $data,
        ];

        return $result;
    }

    /**
     * 操作成功返回值包装
     *
     * @param array  $data
     * @param string $msg
     *
     * @return array
     */
    public static function xzxResponseData (int $code, string $message = '', $data = []): array {
        return [
            "code" => $code,
            "message"  => $message == "" ? "操作成功" : $message,
            "data" => $data,
        ];
    }

    public static function isSuccess ($re) {
        return $re['code'] == XZXResponseCode::SUCCESS_CODE;
    }

    public static function isError ($re) {
        return !self::isSuccess($re);
    }

    public static function buildSuccess ($data = [], $message = 'success', $code = XZXResponseCode::SUCCESS_CODE) {
        return self::xzxResponseData($code, $message, $data);
    }

    public static function buildError ($message, $code = XZXResponseCode::FAILED_CODE, $data = []) {
        return self::xzxResponseData($code, $message, $data);
    }



    // /**
    //  * 操作成功返回值包装
    //  *
    //  * @param array $rows
    //  * @param int $total
    //  * @param string $msg
    //  * @return array
    //  */
    // public static function xzxReturnList($rows = [], $total = 0, $msg = "")
    // {
    //     return [
    //         "code"  => 200,
    //         "msg"   => $msg == "" ? "操作成功" : $msg,
    //         "rows"  => $rows,
    //         "total" => $total
    //     ];
    // }

    // /**
    //  * 操作失败返回值包装
    //  *
    //  * @param int $code
    //  * @param array $data
    //  * @param string $msg
    //  * @return array
    //  */
    // public static function xzxReturnFailedData($msg = "", $code = 500, $data = [])
    // {
    //     return [
    //         "code"  => $code,
    //         "msg"   => $msg == "" ? "操作失败" : $msg,
    //         "data"  => $data
    //     ];
    // }

    /**
     * 自定义打印调试函数
     */
    public static function xzxDebug () {
        // 检查环境参数
        if (!env('APP_DEBUG')) {
            return;
        }

        $args = func_get_args();

        if (PHP_SAPI !== 'cli')
            echo '<pre>';

        $datetime = self::xzxGetDateTime();

        echo PHP_EOL.'---------- debug print begin ----------'.PHP_EOL.PHP_EOL;

        foreach ($args as $v) {
            if (!$v) {
                var_dump($v);
            }
            else {
                print_r($v);
            }
            echo PHP_EOL;
        }

        echo PHP_EOL.'---------------------------------------'.PHP_EOL;

        $debug_backtrace = debug_backtrace();

        $trace = current($debug_backtrace);

        // 获取函数名
        $func = next($debug_backtrace);
        $func = !$func ? null : $func['function'];

        echo "FILE  : {$trace['file']}".PHP_EOL;
        echo "FUNC  : {$func}".PHP_EOL;
        echo "LINE  : {$trace['line']}".PHP_EOL;
        echo "TIME  : {$datetime}".PHP_EOL;

        echo '---------- debug print end   ----------'.PHP_EOL.PHP_EOL;

        if (PHP_SAPI !== 'cli')
            echo '</pre>';
    }

    /**
     * 时间戳转换
     *
     * @param null $time
     *
     * @return false|string
     */
    public static function xzxGetDateTime ($time = null) {
        if (is_null($time)) {
            $time = time();
        }
        return date('Y-m-d H:i:s', $time);
    }

    /**
     * @param $pwd
     * @param $salt
     *
     * @return string
     */
    public static function xzxGenPassWord ($pwd, $salt = "") {
        if ($salt = "") {
            $salt = "xzxkkkkkkk";
        }
        return md5($pwd.'*'.$salt);
    }

    /**
     * @return mixed|string
     */
    public static function xzxGetClientIp () {
        try {
            /**
             * @var ServerRequestInterface $request
             */
            $request = Context::get(ServerRequestInterface::class);
            $ip_addr = $request->getHeaderLine('x-forwarded-for');
            if (self::xzxVerifyIp($ip_addr)) {
                return $ip_addr;
            }
            $ip_addr = $request->getHeaderLine('remote-host');
            if (self::xzxVerifyIp($ip_addr)) {
                return $ip_addr;
            }
            $ip_addr = $request->getHeaderLine('x-real-ip');
            if (self::xzxVerifyIp($ip_addr)) {
                return $ip_addr;
            }
            $ip_addr = $request->getServerParams()['remote_addr'] ?? '0.0.0.0';
            if (self::xzxVerifyIp($ip_addr)) {
                return $ip_addr;
            }
        } catch (Throwable $e) {
            return '0.0.0.0';
        }
        return '0.0.0.0';
    }

    public static function xzxVerifyIp ($realip) {
        return filter_var($realip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
    }

    /**
     * 根据IP获取地区
     */

    public static function getCity ($ip) {

    }

    /**
     * 判断是否存在并且不为空
     *
     * @param $param
     *
     * @return bool
     */
    public static function xzxIsEmptyParam ($param) {
        return (isset($param) && !empty($param));
    }

    /**
     * 当存在且不为空字符串的时候增加参数
     */
    public static function xzxAddSearch (&$param, $search, $key) {
        if (isset($search[$key]) && $search[$key] !== '') {

            $param[$key] = $search[$key];
        }
        return $param;
    }

    /**
     * 空对象
     */
    public static function xzxEmptyObject () {
        return (object) [];
    }

    /**
     * create UUID
     */
    public static function createUUID () {
        $charid = strtoupper(md5(uniqid((string) mt_rand(), true)));
        $hyphen = chr(45);// "-"
        $uuid   = substr($charid, 0, 8).$hyphen.substr($charid, 8, 4).$hyphen.substr($charid, 12, 4).$hyphen.substr($charid, 16, 4).$hyphen.substr($charid, 20, 12);
        return $uuid;
    }

    /**
     * 生成密码
     */
    public static function genPassWord ($pwd, $salt) {
        return md5($pwd.'*'.$salt);
    }

    /**
     * @return array|mixed|string
     * @todo 获取当前域名
     */
    public static function getServerName () {
        $request = Context::get(ServerRequestInterface::class);
        return $request->getUri()->getHost();
    }

    public static function getRequestUri () {
        $request = Context::get(ServerRequestInterface::class);
        return $request->getUri()->getPath();
    }

    /**
     * @return array|mixed|string
     * 生成appid
     */
    public static function createAppId () {
        return substr(md5(time().NumberUtils::random(16)), 8, 24);
    }

    /**
     * @return array|mixed|string
     * 生成appid
     */
    public static function createAppSecret () {
        return sha1(md5(time().NumberUtils::random(16)));
    }

    /**
     * 交易流水号
     *
     * @param string $transType
     *
     * @return string
     */
    public static function createTradeNo ($transType = 'sales') {

        $map = [
            'refund'    => 'TK', // 退款
            'dishonor'  => 'DI', // 拒付
            'frozen'    => 'FR', // 冻结
            'thaw'      => 'TH', // 解冻
            'complaint' => 'CO', // 调查
            'fake'      => 'FA', // 伪冒
            'event'     => 'EV', // 事件订单
            'trans'     => 'TR', // 转账/提现订单
        ];

        $prefix = 'EC';

        if (isset($map[$transType])) {
            $prefix = $map[$transType];
        }

        return $prefix.date('YmdHis').StringUtils::randNumber(5);
    }

    /**
     * 批次号
     *
     * @param string $prefix
     *
     * @return string
     */
    public static function createBatchNo ($prefix = '') {
        return $prefix . date('YmdHis') . StringUtils::randNumber(5);
    }
}
